/*******************************************************************

   NotifyWindow.c
        
        Does open a simple window with some easy gadgets and installs
        also notification for events:
        - DOpus quit
        - DOpus hide
        - DOpus show
        - Diskchange    
                                
*********************************************************************/

#define PARENT  
#include "/includes/Window.h"

/********************************************************************/
// locale prototypes

BOOL OpenDOpusWin( WindowHandle *wh );

BOOL HandleWindow( WindowHandle *wh );

BOOL InstallNotify( WindowHandle *wh ); 
BOOL HandleNotify( WindowHandle *wh );

/********************************************************************/

void OwnWindow( STRPTR args, struct Screen *screen )
{
        WindowHandle          *wh;
        
        if( (wh = AllocMemH(mempool, sizeof(WindowHandle))) ) // allocate some memory
          {
             wh->screen = screen;     // store the screen pointer
                  
             // now the change
                  
             if( InstallNotify(wh) )
               {
                  if( OpenDOpusWin(wh) )   // open the window
                    {
                       // we copy now the arguments into the text gadget
                       // if we have supplied some...
                                 
                       SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) args );
                                                                                                 
                       while( TRUE ) 
                         {
                             wh->signals = Wait( (wh->win ? 1 << wh->win->UserPort->mp_SigBit : NULL) |   // wait for window events if window is open
                                                 1 << wh->notify_port->mp_SigBit  );
                                                          
                             if( wh->signals & 1 << wh->win->UserPort->mp_SigBit )
                                  if( HandleWindow(wh) )
                                       break;              // does end the while loop
                                                          
                             if( wh->signals & 1 << wh->notify_port->mp_SigBit )
                                  if( HandleNotify(wh) )
                                       break;                                                       
                                   
                          }
                                 
                                                if( wh->win ) // again a small change !
                                 CloseConfigWindow( wh->win );
                                        }
                                        
                            RemoveNotifyRequest( wh->notify_handle ); // remove our request
                                 
                                 while( !IsMsgPortEmpty(wh->notify_port) ) // clear the port
                                      ReplyFreeMsg( GetMsg(wh->notify_port) );
                                                
                                 DeleteMsgPort( wh->notify_port ); // and delete him
                         }
                         
                  FreeMemH( wh ); // free our memory
          }                                               
}

/********************************************************************/
// This function does open our window. We could have done this in the
// function OwnWindow() too, but we need this function later again.

BOOL OpenDOpusWin( WindowHandle *wh )
{
        NewConfigWindow ncfgwin;     // we need a NewConfigWindow structure too
                                     // of couse you could also allocate it with
                                                                                  // AllocMemH()...
        
        // and have to fill it
        
        ncfgwin.nw_Parent = wh->screen;  // open on this screen
        
        // getting a localized title...
        ncfgwin.nw_Title  = DOpusGetString( locale, MSG_WINDOW_TITLE );
        
        ncfgwin.nw_Dims   = &cfgwin; // a pointer to the ConfigWin structure
        ncfgwin.nw_Locale = locale;  // the module locale pointer (from modinit.c)
        ncfgwin.nw_Port   = NULL;    // we doesn't supply a port
        ncfgwin.nw_Font   = NULL;    // just taking the screen font
        ncfgwin.nw_Flags  = WINDOW_REQ_FILL      | // fill with stripple pattern
                            WINDOW_AUTO_KEYS     | // handle keys automatic
                                                          WINDOW_SCREEN_PARENT;  // nw_Parent points to a screen
        
        if( (wh->win = OpenConfigWindow(&ncfgwin)) )   // open the window
          {
                  if( (wh->olist = AddObjectList(wh->win, odef)) ) // add the gadgets
                         return TRUE;
                                        
                  CloseConfigWindow( wh->win ); //      in error case do not forget :-)
          }
        
        return FALSE;
}


/********************************************************************/
// we does only close the window, if the closegadget was pressed
// if you want to close it within a gadget, you must only in the
// right case set "stop" to TRUE

BOOL HandleWindow( WindowHandle *wh )
{
         BOOL stop = FALSE;
         ULONG value;
         
         while( !stop && (wh->imsg = GetWindowMsg(wh->win->UserPort)) )
                {
                        switch( wh->imsg->Class )  // let's handle the IDCMP
                          {
                                  case IDCMP_GADGETUP:
                                                          switch( GET_ID(wh->imsg) )
                                             {
                                                                                                                 case GADGET_ID_CYCLE:  // we copy simply the same text to the text gadget
                        
                                                                                 value = GetGadgetValue( wh->olist, GADGET_ID_CYCLE ) + MSG_CLICK_ME;
                                                                                                                    SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) DOpusGetString(locale, value) );
                                                                                                                    break;
                        
                                                          case GADGET_ID_OKAY:   // doing a message
                                                                                 
                                                                                                                                                                                SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) DOpusGetString(locale, MSG_OKAY_DONE) );
                                                                                                                    break;
                                                                                                        
                                                          case GADGET_ID_CANCEL: 
                                                                                 SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) DOpusGetString(locale, MSG_CANCEL_DONE) );
                                                                                                                    break;
                                                  }
                                                                                                                                 
                                                                                                  break;
                                                                         
                                  case IDCMP_CLOSEWINDOW:
                                                          // we can not simply return here, the IntuiMessage must replied first
                                                                                                  
                                                                                   stop = TRUE;
                                                                                                  break;                                                                         
                          }
                                                                 
                        ReplyWindowMsg( wh->imsg );  
                                                          
                        // remember: You should not use any other routines
                        // to get/reply the messages of this window than
                        // GetWindowMsg() and ReplyWindowMsg() !!
           }
                                                         
    return stop;
}

/********************************************************************/

BOOL InstallNotify( WindowHandle *wh )
{
          if( (wh->notify_port = CreateMsgPort()) ) // a private port is enough
            {
                         if( (wh->notify_handle = AddNotifyRequest( DN_OPUS_HIDE | DN_OPUS_QUIT | DN_OPUS_SHOW | DN_DISKCHANGE,
                                                                    NULL, wh->notify_port)) )
                              return TRUE;
                         
                         DeleteMsgPort( wh->notify_port );
                 }
                 
          return FALSE; 
}
 
BOOL HandleNotify( WindowHandle *wh )
{
          BOOL ret_value = FALSE;

          
          while( !ret_value && (wh->notify_msg = (DOpusNotify *) GetMsg(wh->notify_port)) )
            {
                         switch( wh->notify_msg->dn_Type )
                           {
                                        case DN_OPUS_QUIT:  // we should quit
                                                           
                                                                                          ret_value = TRUE;
                                                                                          break;
                                        
                                        case DN_OPUS_HIDE:  // we must close our window
                                                           
                                                                                          CloseConfigWindow( wh->win );
                                                                                          wh->win = NULL;  // do not forget this ! It's a kind of flag...
                                                                                          break;
                                        
                                        case DN_OPUS_SHOW:  // we can reopen our window, if it was closed
                                                           
                                                                                          if( !wh->win )
                                                                 OpenDOpusWin( wh );
                                                                                          break;
                                        
                                        case DN_DISKCHANGE: // we set the value of our text gadget
                                        
                                                            if( wh->win )
                                                                                            {           
                                                                                                         sprintf( wh->buffer, "Diskchange in drive %s", wh->notify_msg->dn_Name );
                                                                                                         SetGadgetValue( wh->olist, GADGET_ID_TEXT, (ULONG) wh->buffer );
                                                                                                 }
                                                                                     
                                                                                          break;                                        
                                }
                         
                         ReplyFreeMsg( (struct Message *) wh->notify_msg );
                 }
                 
          return ret_value;       
}